/*
* 语音合成（Text To Speech，TTS）技术能够自动将任意文字实时转换为连续的
* 自然语音，是一种能够在任何时间、任何地点，向任何人提供语音信息服务的
* 高效便捷手段，非常符合信息时代海量数据、动态更新和个性化查询的需求。
*/

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "../../include/qtts.h"
#include "../../include/msp_cmn.h"
#include "../../include/msp_errors.h"
typedef int SR_DWORD;
typedef short int SR_WORD ;

/* wav音频头部格式 */
typedef struct _wave_pcm_hdr
{
	char            riff[4];                // = "RIFF"
	int				size_8;                 // = FileSize - 8
	char            wave[4];                // = "WAVE"
	char            fmt[4];                 // = "fmt "
	int				fmt_size;				// = 下一个结构体的大小 : 16

	short int       format_tag;             // = PCM : 1
	short int       channels;               // = 通道数 : 1
	int				samples_per_sec;        // = 采样率 : 8000 | 6000 | 11025 | 16000
	int				avg_bytes_per_sec;      // = 每秒字节数 : samples_per_sec * bits_per_sample / 8
	short int       block_align;            // = 每采样点字节数 : wBitsPerSample / 8
	short int       bits_per_sample;        // = 量化比特数: 8 | 16

	char            data[4];                // = "data";
	int				data_size;              // = 纯数据长度 : FileSize - 44 
} wave_pcm_hdr;

char*  sessionID    = NULL;
int    synth_status = MSP_TTS_FLAG_STILL_HAVE_DATA;
char* params1 = "engine_type = local,voice_name=xiaoyan, text_encoding = UTF8, tts_res_path = fo|res/tts/xiaoyan.jet;fo|res/tts/common.jet, sample_rate = 16000, speed = 50, volume = 50, pitch = 50, rdn = 2";

char* params2 ="engine_type = local,voice_name=xiaofeng, text_encoding = UTF8, tts_res_path = fo|res/tts/xiaoyan.jet;fo|res/tts/common.jet, sample_rate = 16000, speed = 50, volume = 50, pitch = 50, rdn = 2";

char* params = "engine_type = local,voice_name=xiaoyan, text_encoding = UTF8, tts_res_path = fo|res/tts/xiaoyan.jet;fo|res/tts/common.jet, sample_rate = 16000, speed = 50, volume = 50, pitch = 50, rdn = 2";

int tts_init()
{
	int         ret                  = MSP_SUCCESS;
	const char* login_params         = "appid = 5fd88d3e, work_dir = .";//登录参数,appid与msc库绑定,请勿随意改动
	
	/* 用户登录 */
	ret = MSPLogin(NULL, NULL, login_params); //第一个参数是用户名，第二个参数是密码，第三个参数是登录参数，用户名和密码可在http://www.xfyun.cn注册获取
	if (MSP_SUCCESS != ret)
	{
		printf("MSPLogin failed, error code: %d.\n", ret);
		return -1;
	}
    return 0;
}

int tts_init2(const char* login_params)
{
	int         ret                  = MSP_SUCCESS;
	//const char* login_params         = "appid = 5fd88d3e, work_dir = .";//登录参数,appid与msc库绑定,请勿随意改动
	
	/* 用户登录 */
	ret = MSPLogin(NULL, NULL, login_params); //第一个参数是用户名，第二个参数是密码，第三个参数是登录参数，用户名和密码可在http://www.xfyun.cn注册获取
	if (MSP_SUCCESS != ret)
	{
		printf("MSPLogin failed, error code: %d.\n", ret);
		return -1;
	}
    return 0;
}

int tts_init3(const char* login_params , int voice)
{
	int         ret                  = MSP_SUCCESS;
	//const char* login_params         = "appid = 5fd88d3e, work_dir = .";//登录参数,appid与msc库绑定,请勿随意改动
	
	/* 用户登录 */
	ret = MSPLogin(NULL, NULL, login_params); //第一个参数是用户名，第二个参数是密码，第三个参数是登录参数，用户名和密码可在http://www.xfyun.cn注册获取
	if (MSP_SUCCESS != ret)
	{
		printf("MSPLogin failed, error code: %d.\n", ret);
		return -1;
	}

	switch(voice) {
		case 1:
		params = params1;
		break;
		case 2:
		params = params2;
		break;
		default:
		params = params1;
	}
    return 0;
}

void tts_close() {
    MSPLogout();
}

int tts_puts(const char *src_text) {
    int ret;
	sessionID = QTTSSessionBegin(params, &ret);
	if (MSP_SUCCESS != ret)
	{
		printf("QTTSSessionBegin failed, error code: %d.\n", ret);
		return -1;
	}
	//printf("input: %s\n",src_text);
    ret = QTTSTextPut(sessionID, src_text, (unsigned int)strlen(src_text), NULL);
	if (MSP_SUCCESS != ret)
	{
		printf("QTTSTextPut failed, error code: %d.\n",ret);
		QTTSSessionEnd(sessionID, "TextPutError");
		return -1;
	}
    return 0;
}

void* tts_get_pcm(unsigned int *audio_len , int *err) {
	int ret;
    const void* data = QTTSAudioGet(sessionID, audio_len, &synth_status, &ret);
	//printf("tts_get_pcm error code:%d\n",ret);
	if (MSP_SUCCESS != ret) {
		printf("QTTSAudioGet failed, error code: %d.\n",ret);
		QTTSSessionEnd(sessionID, "AudioGetError");
		*audio_len = 0;
		*err = -1;
        return NULL;
    }
			 
	if (NULL != data) {
		return data;
	}
	if (MSP_TTS_FLAG_DATA_END == synth_status) {
		*err = -1;
		QTTSSessionEnd(sessionID, "Normal");
		return NULL;
	}
	return NULL;
}
/*
int main(void) {
	unsigned int alen;
	void* data;
	int err;
	tts_init();
	tts_puts("你好朋友。");
	while(1){
		data = tts_get_pcm(&alen,&err);
		if (err==-1){
			break;
		}
		if ( data!=NULL )
			fwrite(data,1,alen,stdout);
	}
	
	tts_close();
}
*/
